package org.baeta.services;

import javax.jws.WebService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.baeta.client.CountryInfoClient;
import org.baeta.client.CountryInfoJSONClient;
import org.baeta.client.WeatherObservationClient;
import org.baeta.client.WeatherObservationJSONClient;
import org.baeta.model.GeoName;
import org.baeta.model.JSON2ModelFactory;
import org.baeta.model.WeatherObservation;
import org.json.JSONObject;

/**
 * Service implementation class
 *
 * @author <a href="mailto:rui.baeta@gmail.com">Rui Baeta</a>
 * @version 26-Sep-2012 01:05:45
 */
@WebService(endpointInterface = "org.baeta.services.CountryInfoService")
public class CountryInfoServiceImpl implements CountryInfoService
{
    private static final Log LOG = LogFactory.getLog(CountryInfoServiceImpl.class);

    @Override
    public CountryInfo getCountryInfo(final String countryCode)
    {
        // final webservice response
        final CountryInfo countryInfo = new CountryInfo();

        // launch request in a separate thread
        Thread countryThread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    LOG.info("Running CountryInfoClient...");
                    CountryInfoClient countryClient = new CountryInfoJSONClient();
                    JSONObject jsonCountryInfo = (JSONObject) countryClient.getCountryInfo(countryCode);
                    GeoName countryBean = (GeoName) JSON2ModelFactory.getInstance().createBean(jsonCountryInfo);
                    countryInfo.setGeoName(countryBean);
                }
                catch (Exception e)
                {
                    throw new RuntimeException("Exception running CountryInfoClient", e);
                }
            }
        });
        countryThread.start();

        // could not execute in parallel, because thread 2 needs geo coords from thread 1
        // (I could not find web service for ICAO code, so I used geo coords...)
        // when using parallelism, join invocations would be at the end 
        try
        {
            countryThread.join();
        }
        catch (InterruptedException e)
        {
            throw new RuntimeException("Exception running CountryInfoClient", e);
        }


        // launch request in a separate thread
        Thread weatherThread = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    LOG.info("Running WeatherObservationClient...");
                    GeoName countryBean = countryInfo.getGeoName();
                    if (countryBean != null)
                    {
                        WeatherObservationClient weatherClient = new WeatherObservationJSONClient();
                        JSONObject jsonWeather = (JSONObject) weatherClient.getWeatherObservation(countryBean.getNorth(), countryBean.getSouth(), countryBean.getEast(), countryBean.getWest());
                        WeatherObservation weatherBean = (WeatherObservation) JSON2ModelFactory.getInstance().createBean(jsonWeather);
                        countryInfo.setWeatherObservation(weatherBean);
                    }
                    else
                    {
                        LOG.info("Cannot run WeatherObservationClient because CountryInfoClient failed.");
                    }
                }
                catch (Exception e)
                {
                    throw new RuntimeException("Exception running WeatherObservationClient", e);
                }
            }
        });
        weatherThread.start();
        
        try
        {
            weatherThread.join();
        }
        catch (InterruptedException e)
        {
            throw new RuntimeException("Exception running WeatherObservationClient", e);
        }

        return countryInfo;
    }
}
